perm filename EDGCUR.PUB[SYS,HE]3 blob
sn#021162 filedate 1973-01-17 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00026 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00004 00002 .TURN ON "\{↓_∪←#"
00009 00003 .SEC INTRODUCTION
00011 00004 .SS EDGE TRACING ALGORITHM
00018 00005 .SS CURVE FITTING ALGORITHM
00030 00006 .SS CALLING CONVENTIONS
00034 00007 .SEC MAIN COMMANDS
00037 00008 .SS COMMAND DESCRIPTIONS
00039 00009 .SS FIND - find and trace an object
00046 00010 .SS(FINE - do a fine scan of a previously traced object)
00058 00011 .SS REJECT - delete data structure for an object
00063 00012 .SS RELOOK - see if the object is still there
00065 00013 .SS COMPACT the data structure
00071 00014 .SS FIT straight lines to the object's edges
00075 00015 .SEC MINOR COMMANDS
00079 00016 .SS GETDATA - get edge follower output
00084 00017 .SS GLBDMP - get curve fitter output
00090 00018 .SS SETVAL - change a variable
00098 00019 .SS GETVAL - look at a variable
00099 00020 .SS XEQ - miscellaneous commands
00106 00021 .SEC(STRINGS OUTPUT BY PROGRAMS)
00111 00022 .SS(ERROR OUTPUT)
00119 00023 .SEC DATA STRUCTURES
00122 00024 .SS EDGE INTERNAL DATA STRUCTURE
00127 00025 .SS GLOBAL DATA STRUCTURE FROM CURVE
00131 00026 .SS CAMERA TRANSFORM
00133 ENDMK
⊗;
.TURN ON "\{↓_∪←#";
.MACRO COL(I,A,B,C,D) ⊂BEGIN TABS A,B,IF LENGTH("C") THEN C ELSE B;
. IF LENGTH("D") THEN INDENT I,A-1,D ELSE INDENT I,A-1;⊃;
.TABBREAK
.!SPACES ← "#####################################################" ;
.!HYPHENS ← "--------------------------------------------------------------" ;
.MACRO FORMAT ⊂TURN ON "↑↓[]&_∪∂∞\αβ#←→"⊃;
.MACRO REF(A) ⊂"Section ";SUBSECTION! A⊃;
.MACRO STANDARD FRONT(SECPRINT, SSPRINT, PAGEPRINT, INDEXCHAR) ⊂
.IF "SECPRINT" ≠ NULL THEN
. START
. COUNT SECTION PRINTING "SECPRINT"
. MACRO SEC(NAME) ⊂ SECNAME ← SSNAME ← NULL ;
. NEXT PAGE; NEXT SECTION;
. BEGIN
. FORMAT CENTER
↓_SECTION {!}_↓
. SKIP 1;
↓_NAME_↓
. SKIP 3
. SECNAME ← "NAME"
. SEND CONTENTS ⊂ SKIP 1;
{SECTION!}∂8NAME{BREAK ⊃
. END ⊃
. END ;
.IF "SSPRINT" ≠ NULL THEN
. START
. SUBBING ← "YES"
. COUNT SUBSECTION IN SECTION PRINTING "SSPRINT"
. MACRO SS(NAME) ⊂ SSNAME←"NAME"; IF LINES<7 THEN NEXT PAGE; NEXT SUBSECTION;
. START
. FILL SKIP 2 TURN ON "{←∂∞→#↓_"
. SEND CONTENTS ⊂
∂(13){SUBSECTION!}∂(23)NAME\∞ ∞.∞ →#{PAGE!}
. ⊃
. END
.ONCE INDENT 0;
{!}.###↓_NAME_↓
. SKIP 1;
. TURN OFF ; ⊃
. END
.ELSE SUBBING ← "NO"
.IF "PAGEPRINT" ≠ NULL THEN COUNT PAGE IN SECTION PRINTING "PAGEPRINT"
.INDEXING ← IF "INDEXCHAR"=NULL THEN "*" ELSE "INDEXCHAR" ;
.IF "INDEXCHAR" ≠ NULL THEN
. START
. AT INDEXING PHRASE INDEXING ⊂
. "PHRASE" ; TURN ON "{"
. SEND INDEX ⊂}<<{PAGE}#PHRASE#{⊃
. TURN OFF ⊃
. END
.ELSE INDEXING ← "NO"
.INSERT CONTENTS
.PORTION MAINPORTION
.SECNAME ← SSNAME ← NULL
. ⊃
.
.MACRO STANDARD BACK ⊂
.SECNAME ← SSNAME ← NULL
.IF INDEXING ≠ "NO" THEN
. START
. PORTION INDEX
. WASWORD ← WASLETT ← WASPG ← NULL ;
. AT "<<" PGNO "#" PHRASE "#" ⊂ LETT ← "PHRASE"[1] ;
. IF LETT ≠ WASLETT THEN IF LINES<6 THEN NEXT PAGE ELSE SKIP 2 ;
. IF "PHRASE" ≠ WASWORD THEN START BREAK }PHRASE##PGNO{ END
. ELSE IF "PGNO" ≠ WASPG THEN },#PGNO{ ;
. WASPG ← "PGNO" ; WASLETT ← LETT ; WASWORD ← "PHRASE" ; ⊃
. NOFILL FORMAT INDENT 0,0 PREFACE 0
←INDEX
. SKIP 4
. SECNAME ← "INDEX"
. RECEIVE "##"
. SECNAME ← NULL
. END
.PORTION CONTENTS
.COUNT PAGE PRINTING "i"
.FILL NOJUST FORMAT CRBREAK
.INDENT 0,30,10 PREFACE 1 TABS 30,33,36,39,42,45,48,51,54,57,60,63
←↓_T A B L E O F C O N T E N T S_↓
.SKIP 3
.IF SUBBING THEN
←SECTION→PAGE
.SKIP 2
.SECNAME ← "TABLE OF CONTENTS"
.RECEIVE
. ⊃
.STANDARD FRONT("I","!.A","!-1",%)
.EVERY HEADING("EDGE AND CURVE DOCUMENTATION",,{SECNAME})
.EVERY FOOTING(,{PAGE!})
.INDENT 8;
.SEC INTRODUCTION
.SS THIS DOCUMENT
This document is the most complete description of the edge follower
and curve fitter available. These programs are two seperate jobs, found on
SYS,HE as EDGE and CURVE. CURVE normally runs as a satellite of the edge
follower. In this document, EDGE and CURVE are assumed to be running as
subjobs of the hand/eye monitor, unless otherwise specified. Either job
can be run seperately, with or without the monitor. EDGE funtions the
same with or without the monitor, and basically the same with or without
CURVE being available (except for the commands which reference CURVE);
CURVE, however, behaves differently in each case.
Many variables can be
set from the console or other jobs to control the behavior of EDGE and
CURVE. The descriptions for the commands assume, unless stated otherwise,
the settings in effect when the programs are first started.
When a condition can be changed, the description will state "controlled
by " if a variable controls the condition, or "changed by" if the condition
is altered by a command. A reference will be given to the subsection which
describes the command mentioned; for changing control variables see {REF CVAR}.
.SS EDGE TRACING ALGORITHM
.FOLLOWER:SUBSECTION!
Edges can be detected by several methods, depending on the command
used. Once an edge has been detected, however, the same inner loop is used
by all commands to follow the edge.
The new %Hueckel operator% (described in %HELIB.KKP[S,DOC]%) is used to
track the edge (or line). Its thresholds are set as follows:
.TURN ON "α"; COL(10,5,10,,5);
%DIFF%α←(1α.5[controlled by %DIF%]*(CASE BITS-3 OF (1α.0, 1α.0, 2α.0, 2α.0))↑2 where BITS is
the sample size of the input; 4 for TV input and 3-6 for disk input.
%CONF%α←α.90 (controlled by CONF)
.END;
At each point where the edge has been detected, operator 2 is moved
1α.4 resolution elements (controlled by %SPACE%) along the edge and applied
at that point. If no edge is found, operator 1 is tried at the same place.
If still no edge is found, one of the following actions is taken:
.COL(5,10,15,20,5);
1.\If the point is outside the field of view of the TV, the scan is
terminated and an attempt is made to scan from the starting point in the
opposite direction, if that has not already been done. The limits of the TV
field of view are initially set to the limits that the TV can see (controlled
by %TMAX%, %BMAX%, %RSMAX%, and %LSMAX%) and edges which extend outside this
area are terminated, rather than followed further (controlled by %SLIM%).
2.\If the edge was lost, the accomodation routines are called to
adjust the TV clip levels and sensitivity and then the operator is
applied at the point again.
3.\If accomodation failed, or the operator indicated a noisy area,
the operator is moved in two concentric semi-circles centered on the last
point found, to try and pick up the edge further out. If this fails, the
edge has been lost and the program tries to scan in the opposite director
as described in 1 above. It also checks for any other endpoints near where the
edge was lost. If one is found, the edge is linked to it.
.END;
If the edge was found, but at a point where it has recently been found
before, the scan is looping and the actions of 3 above are carried out. If the
new edge point has not been seen before, the program returns to apply the
operator at the next point, after updating the display (controlled by %DISTST%)
and the local data structure. All points found during a single trace are stored
together as a single edge segment.
If the point found is near an object already traced, the current edge segment
is linked to that object and the scan terminated. If the point is found to be
near the other endpoint of the edge segment, the scan is terminated and a closed outline
has been found. If the point is near the endpoint of a different edge segment,
the two edge segments are combined.
If the object has less than 4 edge points when tracing is finished, it
is deleted. If any edge segment has less than 3 points, it is deleted. If the
data structure for the object still contains dangling edges which have only
been traced in one direction, the program tries to trace them in the reverse
direction.
The output of this routine is a local data structure describing the
topology of the scene thus far scanned. There is a circular list of objects
each of them pointing to a circular list of edge segments, each of them pointing
to a circular list of edge points. There is at most one closed edge segment
for each object, denoting an edge with was traced clear around to the starting
point. All other edge segments are flagged with information on why they terminated.
This structure can be passed to the curve fitter (see {REF(CURVE)}) or
dumped on the disk in a format to be passed to other jobs (see {REF (GETDATA)}).
For a complete description of the internal data structure see {REF(EDGSTR)}.
.SS CURVE FITTING ALGORITHM
.FITTER: SUBSECTION!
The curve fitter has only one main command and its algorithm
never varies; it can be modified only by changing thresholds.
It makes six passes over the data; one to fit straight lines to the
edge points, and five to clean up the outline obtained.
In the first pass, each edge segment found by the edge follower for
the object is considered separately. If it is not a closed segment, its
entire set of points is used as the first try
at a line segment (often refered to as a line hereafter) and is put in a stack;
otherwise, one point is
picked at random and another is picked to be as far as possible
from it. These two points are used to break the edge segment into two sets of
points to be used as initial guesses for lines, both of which are stacked.
The rest of the pass is a loop. All the points in the current
set are used to calculate the coordinates of the
line which makes the best least squares fit of the points. The error
is calculated and if it is less than .2, the line is accepted and the
program goes on to the next set of points, if any. If the error
is two large, the point in the current set with
the maximum distance between it and the line is selected to break the
current set of points into two sets, one of which is stacked and the
program returns to apply the same process to the other set of points.
When a new line is accepted, the intersection of it with the last line
found is considered and the point nearest the intersection in each set
is checked to determine which of the two lines it is closest to. If it is
closest to the line for the other set of points, it is
shifted to that set and the line equations of both lines are recalculated.
This continues until there are no shifts.
At the conclusion of this pass, the edge segment has been broken up into one or
more line segments, each of which is a very good fit for the edge points
found in that part of the image. Hopefully, all true corners have been
found, along, usually, with many corners which should not exist.
The second pass merges short line into longer lines, if
possible. Three consecutive lines are considered at a time. Lines 1 and
2 are combined and a line equation calculated; lines 2 and 3 are used to
calculate a second line equation. The least squares error of each line is
calculated, divided by the number of points in the line and the two errors
compared. If the error of the first line is less than .7 and less than the
error of the second line, it is accepted as a valid line; otherwise, the two
original lines which were combined are retained. Then lines 2 and 3, if
the combined line was not accepted, or the combined line and line 3
are processed along with the next adjacent line. The program goes
through the complete set of lines until no lines have been merged
in a complete pass through the set.
In the third pass, all lines less containing less than five
edge points and which are not at the end of one of the original edge segments is
deleted [currently suppressed for complex - KKP] and the resulting set of
lines is intersected to find their exact intersections.
If this intersection is futher than 12 points from the position of the corner
derived from the set of edge points the lines were formed from, it is rejected
as a bad corner. If the distance between the two vertex points is over 32 a
short line is placed between the ends of the two lines on the assumption
that the curve fitted incorrectly deleted a short line; otherwise, the
corner derived from the edge points is retained.
This set of vertex
points is all that is retained for the remainder of the processing.
In pass four the program has a table of all vertices, with dangling
vertices marked. A dangling vertex is one which appears at the endpoint of only
one line. For each dangling vertex, the line containing that vertex is intersected
with all other lines. All lines whose intersection with the dangling line is
within 30 of the dangling vertex are considered further. Of these lines,
the one whose intersection is closest to the dangling vertex and has the
intersection either on the other line or, if the other line is also dangling,
within 15 of the other dangling vertex, is found. If the intersection is
within 4 of the end of the other line, the dangling vertex is set equal to that vertex
;otherwise, the intersection is saved as the new vertex for the dangling
line(s) and they are tested in case they are parallel. There is some minor glitching
here for funny cases which occur but the above is correct, just not quite
complete.
In pass five all vertices within 4 of each other are set to their
average coordinates and in pass six all lines of zero length are deleted.
After the final set of line segments for the object has been
obtained, the program generates the subset of them which may be part of a
closed outline. These are the lines both of whose vertices are shared by
at least two lines, both of which are part of the closed outline. This
set is generated by successive passes through the lines marking all lines
either with dangling vertices or a vertex shared only by lines with a dangling
vertex. When a complete pass marks no more lines, all lines not marked are
part of the closed outline. The dangling lines are deleted from the internal
structure and put in the global model as a seperate array in case any later
programs want to process them further.
The final step of the curve fitter is to generate the remainder of the
global structure for the object, which is the sole output of the program (for
a description of the structure generated see {REF(CURSTR)}).
To generate the regions of the object, a set of counters, one for each line, is
cleared. Then the program goes into a loop. If all lines have a count of two,
the loop is finished; otherwise, the vertex which is part of a line with count
less than two and which is the lowest in the TV image of the object is found.
A vertcal line with that vertex as its upper end is assumed. Starting with
that line, an inner loop is executed. The line is found which has a count less than two and which makes
the smallest positive angle with the original line, moving clockwise from the
original line. This is the first line bounding the region. This line has
its count incremented and the inner loop is repeated starting with this line. For
the rest of the inner loop however, the small counterclockwise angle is used, except
for the first region being found (this is the 'outside' region of the object).
When the starting vertex is found again the region is finished and the program
returns to look for a new lowest point.
.SS CALLING CONVENTIONS
.CONV: SUBSECTION!
The edge follower and curve fitter accept input either by means of
the user's teletype (TTY) or message procedures (MP) and most commands can
be executed from either. If a command functions differently depending on
which way it was called, this will be pointed out in its description.
Except for the command %GLBDMP%, all MPs go to the edge follower,
which has as its logical name "EDGE". It acknowledges, but does not kill,
all MPs sent to it. For GLBDMP, the logical name of the curve fitter is
"CURVE". The MP declaration will be given just before the description of
each command; if it is missing, the command can only by executed from the TTY.
∪All commands from the TTY go to the edge follower, which uses MPs
internally to communicate with the curve fitter if it is available. The
command when typed is generally the same as the message procedure call,
with the parenthesis and commas replaced by spaces. The exact format will be
given before the description of the command if it can be executed from the TTY.
Many commands have items as parameters. In the case of items generated
by the commands, they are typed as decimal numbers just as they were typed
back at you from the command which generated them (read about the main commands
to understand this). Two special items are used, %EVERY% and %NIL%. These are
represented, when typing, as -1 and 0 respectively.
.SS LOADING AND COMPILING CONVENTIONS
.LOAD: SUBSECTION!
EDGE and CURVE cannot be loaded by RPG commands; you must run the loader
and give command strings directly to it. The command strings are:
.BEGIN VERBATIM
CURVE with RAID:
GLBLOW[1,3],/VCURVE[SYS,HE]/G
CURVE without RAID:
GLBLOW[1,3],CURVE[SYS,HE]/G
EDGE with RAID:
GLBLOW[1,3],/VCONTRL[SYS,HE]/G
EDGE without RAID:
GLBLOW[1,3],DD[SYS,HE],CONTRL[SYS,HE]/G
.END
DD must be loaded, in the last string, in the position shown or the
command decoder will not execute certain commands (%GETVAL%, %SETVAL%, %XEQ%,
and the %miscellaneous commands%).
If it is necessary to recompile SAIL programs before loading, this is
usually done by COMP /COMP @RPG while logged in on SYS,HE. If only the files
for EDGE and CURVE must be recompiled, they are: CONTRL, EDGE, MISEDG, INNER,
SCANER, CURVE, and MISCUR.
.SEC MAIN COMMANDS
The commands described below activate the main loops of the edge
follower and curve fitter in various ways. If you are doing simple things
they may be all you need. FIND and FINE are explained in some detail, with examples.
Other commands which are variations of FIND assume you understand it.
.SS MAIN COMMAND RESPONSES
.RESPONSE: SUBSECTION!
Each of the main commands returns the results of its execution to the
calling job, or TTY, by means of a response message procedure or output string.
The messsage procedure is declared as
.BREAK}←%RESPONSE%(STRING NAME; INTEGER OBJECT, STATUS){SKIP 1; CONTINUE
where NAME is one of the commands. When a 'FIND response' is refered to below,
for example, it means a response with NAME←"FIND". OBJECT is the numeric representation
of the item for the object processed, or of the special item %NIL%. Note that
it is an integer instead of the item; the item is CVI(OBJECT). This is done
so the message procedure trace of the response will print the number. Then you
have it in case you want to type commands to the edge follower refering to that
object. STATUS tells the calling program what happened, including unusual or
error conditions.
If the command came from the TTY, the response is typed on the TTY in the
form
.BREAK}←NAME###CVS(OBJECT)###CV[O]S(STATUS){SKIP 1;CONTINUE
Note that the status may be returned in octal or decimal, depending
on the command. If the item for OBJECT is NIL, the
string "NIL" is substituted for it. See {REF(FIND)} and {REF(FINE)} for
examples of responses.
.SS COMMAND DESCRIPTIONS
Each command description begins with the message procedure declaration
(MP) and typed command format (TTY), if any. The OUTPUT numbers refer to the
strings which may be typed out if the typing flags (TYP_EDG or TYP_CUR) in the
global model are turned on, either by the calling program or the hand/eye
monitor.
The strings and their meaning can be found in
{REF(OUTPUT)}.
The ERROR numbers refer to error messages which will be typed irregardless of
the typing flags when an error condition is present which the program does not
feel the calling job can handle. Normally they require operator intervention; or
else a restart of the programs involved. The error messages and their meaning
can be found in {REF(ERROR)}.
.SS FIND - find and trace an object
.FIND: SUBSECTION!
.BEGIN VERBATIM
TTY: FIND ARG
MP: FIND(ITEMVAR ARG);
OUTPUT: 1-18
ERRORS: 1-17, 19-21, 26-27
.END
This command finds an edge and then calls the edge follower to trace
the object (see {REF(FOLLOWER)} for algorithm). If ARG=NIL, the command will
terminate when at least one object has been found or the end of the scan is
reached. If ARG=EVERY, the entire image will be scanned to find as many
objects as possible. If ARG is anything else, the result is the same as
ARG=NIL, except that if the item given for ARG appears in global set %OLDBLOB%,
that item will be associated with the first object found (this feature is mainly
for the %RELOOK% command); otherwise, a new global item is created for each
object found.
If job CAMERA is running, it is automatically called the first time
through and whenever the camera is moved or focused to update the camera
transform.
The scan starts at one corner of the field of view (limits controlled
by %TMAX%, %BMAX%, %RSMAX%, and %LSMAX%; starting corner controlled by
%XINCR% and %YINCR%) and scans horizontally (direction and spacing controlled
by %XINCR%), while moving the scan line vertically (direction and spacing
controlled by %YINCR%). At each point the program calculates the absolute intensity
difference with the last point on the same horizontal line. If this difference
is greater than a threshold (controlled by %TTHRES%), Hueckel's operator is
scanned between the two points to find the exact location of the edge. If no
edge has been seen there before, the inner loop is called to trace the object.
Once the object has been found, the coordinates where it was first seen
are stored and the next %FIND% command will start scanning at that
point (changed by the %START% command, see {ref(MISCCOM)}). If the corner
diagonally opposite the starting corner is reached, the scan is reset to the
starting corner again.
At the end of the command, a 'FIND' response is returned for each
object traced, giving the item number and status. Some of the items may have
been returned previously. If they appear again, more edge points have been
found for this object. The command always finishes with a 'FIND' response
with ARG=NIL. If this is the only response, no objects were found.
STATUS is given in octal and is decoded as follows:
.COL(5,10,15,0,5);
-2\control variables were altered incorrectly and are now inconsistant.
No tracing was done.
-1\scan finished (goes with ARG=NIL)
0\a closed curve was traced and nothing else
1\at least one edge being traced was lost due to the failure of the
accomodation routines
2\the trace intersected either the edge it was tracing other than
at the starting point, another edge of the same object, or an edge of a
previously traced object. In the last case, the objects are merged and the
item number returned is that of the old object.
4\at least one edge went outside the limits of the area being scanned
and %SLIM% was FALSE (normal case), or it went outside the TV field of view.
100\no closed outline was found for this object
.END
The status numbers are ORed together. If STATUS<100, then an outline
suitable for SIMPLE has been found. If STATUS≥100, no such outline is
available, although further tracing in the area might find enough lines to
complete the outline, or the curve fitter might be able to complete it.
EXAMPLE: if you do not understand, read {REF(CONV)} and {REF(RESPONSE)}
again.
.BEGIN VERBATIM
type: FIND 0 (0 equivalent to NIL when typing commands)
program responds, when finished:
FIND 4732 1
FIND 4730 104
FIND NIL
.END; SKIP 1; CONTINUE;
This means two objects were found. The first, 4732, has at least two edge segments,
one of which is a closed outline, and at least one other was terminated when it was
lost. The second object, 4730, has at least one segment which went outside the
field of view, but no segment is a closed outline.
.SS(FINE - do a fine scan of a previously traced object)
.FINE: SUBSECTION!
.BEGIN VERBATIM
TTY: FINE ARG
MP: FINE(ITEMVAR ARG);
OUTPUT: 1-18
ERRORS: 1-17, 19-21, 23, 26-27
.END;
The %FINE% command looks very hard at outlines of objects already
traced to try to find additional edges connected to them. ARG is the
object item to be used; EVERY causes every object found to be processed
unless it had been previously processed. An object cannot be FINE
scanned twice. ARG=NIL is not allowed.
The command places rectangles on the field of view and scans
the entire interior of them using Hueckel's operator with a scan increment
equal to the radius of the operator. If an edge point is found at a place
where none has been seen before, the edge follower is called to trace it.
The trace is allowed to go outside the area of the rectangle if necessary
to complete the scan. If any objects other than the one the command was
processing is found, or rediscovered, during the scan, it will be added to
the list of objects to be processed. A 'FIND' response is returned for
every object traced. The command finishes with a 'FINE' response. The
object number will be the original item given as ARG, NIL if ARG was
EVERY or the item given did not exist. STATUS is normally 0 and means
nothing.
This commands functions in two modes, depending on whether or not
the curve fitting is available to receive message procedures. The main
difference between the modes is the way the scan rectangles are set up.
If the curve fitter is not available, for each object to be
processed a rectangle is calculated which entirely covers the object. After
the rectangle is scanned the new limits of the objects are checked and, if
they are now larger due to more edges having been found, a new rectangle
is set up covering the area not covered previously. This continues until
the size of the object does not increase. Then the same processes is
applied to the next object, if any, waiting, unless that object is
wholely contained in one of the previous rectangles. The program does
sometimes scan the same area more than once but it tries hard to catch
the most common cases of overlap. This mode is the most thorough method
of scanning and also very slow. If the curve fitter is available but you
want to force this mode, set the global flag YES_CUR false. Be sure to set
it true again when you are done or no other program will be able to access
the curve fitter.
If the curve fitter is available, each object to be processed has its edges
fit to straight lines and a list of the corners created, with corners very close together
being counted as one corner. Then, a rectangle is placed over each corner causing
a scan of the area near that corner; operating on the assumption that any further
edges will meet the current edges at a corner. When all of them have been checked,
the object is passed to then curve fitter again and any new corners found are
checked. This continues until no new corners are found. Then a rectangle is
placed over the entire objects and a very coarse scan is applied to pick up any
long edges which might have been missed. Normally this is the entire procedure in
this mode. It is possible, however, by means of procedures %COLON% and %COLOFF%
to cause this mode to repeat for each object with each color filter. See
{ref(MISCCOM)} for more details. Two commands are recognized in this mode. Both cause the
the program to terminate processing of the current object. NEXT causes the
processing of the next object, if any, to start. CANCEL terminates the command.
The commands are noticed each time the program starts scanning to look
for an edge. If the coarse scan is in progress, they are also noticed at the
begining of each line of the scan.
EXAMPLE: continuing the example given for FIND, if we want to fine scan
the first object found, we type:
.BEGIN VERBATIM
FINE 4732
the program responds:
FIND 4730 4
FIND 4726 0
FINE 4732 0
.END CONTINUE
This means no more edges were found for object 4732, since there is no FIND response
for it, but object 4730 was near enough to 4732 to be seen also and more
edge points were found for it, creating a closed segment. A new object, 4726,
was also found, and contains only a closed segment.
.SS REJECT - delete data structure for an object
.REJECT: SUBSECTION!
.BEGIN VERBATIM
TTY: REJECT ARG
MP: REJECT(ITEMVAR ARG);
OUTPUT: none
ERRORS: none
.END
The object specified by ARG, or all objects if ARG=EVERY, is deleted,
both from the edge followers data structure and from the portion of the global model
created by the edge follower and curve fitter (see {ref(CURSTR)} for a description
of curve fitter data structure). The item itself is not deleted and is returned
with the '%REJECT%' response; STATUS will be zero. At the end of REJECT(EVERY),
or if the object given does not exist, the response will have ARG=NIL and
STATUS=-1. As a bonus, the edge follower's display will be
turned off for each object deleted. Once an object has been deleted, future
scanning with the edge follower may cause it to be traced again. If you do not
want the object and do not want to see it again, do not reject it; just ignore
it. If you do not want it but would be interested in another trace (the
current one is bad) rejected it.
.SS RELOOK - see if the object is still there
.RELOOK: SUBSECTION!
.BEGIN VERBATIM
TTY: RELOOK ARG
MP: RELOOK(ITEMVAR ARG; INTEGER X,Y);
OUTPUT: 1-18
ERRORS: 1-17, 19-21, 26-27
.END
The object specified by ARG is deleted (by REJECT) and the edge follower
is called to look for it again. The first object found is assumed to be it.
The program sets up a rectangle slightly larger than the object. If X and Y are
zero, or the command was executed from the TTY, the rectangle is centered at
the center of the object; otherwise it is centered at (X,Y). The scan starts
near the middle of the left side of the rectangle. Only objects inside the
rectangle will be found but, once an object is located, the scan will follow
its edges outside the rectangle if necessary. 'FIND' responses will be returned
for each object found, if any. The final output is the '%RELOOK%' response with
ARG=NIL and STATUS=-1 if ARG was EVERY (which is illegal) on entry or no
object was found; STATUS=0 otherwise. The object will be assigned the
item in ARG on entry. This is useful if you think the object may have been
moved, or if you know it has been moved and want to find it, given its
approximate position.
.SS COMPACT the data structure
.COMPACT: SUBSECTION!
.BEGIN VERBATIM
TTY: COMPACT ARG
MP: COMPACT(ITEMVAR ARG);
OUTPUT: none
ERRORS: 25
.END
This command deletes the edge points from the edge follower's data
structure for this object, which recovers a great deal of core, and turns
off the edge follower's display, if any, for the object if global flag
YES_II is true (the II control program is running and will take over the
display). Future scans b the edge follower will jump over the area occupied
by the object without looking at it, speeding up the scan.
Any new edges which link to a compacted object will be immediately deleted.
The command needs a list of the object's
corner coordinates whih it obtains in one of two ways. Since the object must
be curve fitted before this command can be executed for it, the curve fitter
data structure should exist in the global model and can be used. If SIMPLE
has processed the object, it has generated a new item to specify the
body it has recognized, as opposed to the object item the edge follower has
been using, and some more global data structure linked to this new item.
If the latter data structure exists it will be used in preference to the
curve fitter's data structure. To retrieve it, the calling program must
have put the body item (from SIMPLE) in global itemvar ITVAR_II; put NIL
or something else safe in it otherwise. The object cannot be compacted more
than once.
ARG=EVERY is illegal for this command. If ARG is an object in the
edge follower's data structure it will be compacted. If ARG is not an item
known to the edge follwer, a new object is generated in its data structure,
with item ARG, and it is compacted. This last option allows a program
using the edge follower to specify an object it is not to look at while
scanning by generating either of the global data structures mentioned,
using the known locations of the outside corners of the objects, and
calling %COMPACT% with the new item.
Also, if the TV is moved, call REJECT to get rid of the old
data structure and get the new camera transform. Run the corners, in TV
coordinates, through the new transform to get new TV coordinates, put them
back in the global data structures, and call compact with the old item
number to generate a new compacted structure reflecting the object's current
position in the field of view. Only those lines, if any, in the current
field of view are stored in the data structure. Lines partially in the
field of view will be truncated.
After an object has been compacted, the only edge follower commands
which can refer to it are REJECT and RELOOK. A 'COMPACT' response is returned
for each object compacted with ARG containing its item number. STATUS contains:
.COL(5,10,15,,5)
-2\Object ARG has neither association available (ARG=NIL in response)
-1\Object already compacted or ARG=EVERY on entry (ARG=NIL in response)
0\object ARG compacted using SIMPLE data structure
1\object ARG compacted using CURVE data structure
.END
.SS FIT straight lines to the object's edges
.CURVE: SUBSECTION!
.BEGIN VERBATIM
TTY: FIT ARG
MP: FIT(ITEMVAR ARG);
OUTPUT: none
ERRORS: 28-30
.END
If the curve fitter is running and linked to the same global segment
as the edge follower, the edge points for each object will be passed to it by
means of a message procedure and, after acknowledgment, the lines will be displayed.
The user cannot call the curve fitter directly by a message procedure (unless
he can provide an array of edge points in the proper format (see {REF(PNTSTR)}).
If the curve fitter is not available, the edge points for each object will
be dumped on the disk in the same format. Dumping on the disk can be forced
even if the curve fitter is available by means of the %GETDATA% command. See
{REF(GETDATA)}) for a description of the GETDATA command, including how the
disk file is specified. The curve fitter can be run by itself off of the files
put out by GETDATA.
If ARG is an object item, that object will be processed as described above
(see also {REF(FITTER)} for a description of the curve fitting heuristics) and a
'%FIT%' response returned with the item number and status. If ARG=EVERY, all
objects will be processed, except that the program will not curve fit an object
twice unless, after curve fitting, more edges are traced which connect to the
object. In this case, curve fitting can be done again to include the new segments
which might produce a better, or more complete, fit. See {REF(CURSTR)} for a
description of the data structure produced by FIT.
The status word in the response will contain one of the following:
.COL(5,10,15,,5)
-1\If ARG=EVERY on entry, this means all objects have been fit. The
response for each object has already been returned. Otherwise, either the object
requested did not exist, has already been curve fit, or had less than three lines
after fitting (in which case the object was deleted). ARG=NIL in this respose.
0\fit ok
1\fit ok but no closed curve was found. SIMPLE will fail on this object.
.end
.SEC MINOR COMMANDS
.SS INTRODUCTION
These commands are used to alter various features of the main
commands, set special modes of operation, and cause special dumps of
data structures. Several of the message procedures have, as one of their
arguments, 'REFERENCE BOOLEAN FLAG', which returns an error flag. This flag
will be accessable to the calling program only if FLAG is a global variable.
If the command is executed from the TTY, the error flag is not needed; the
control program yells at you if there is a mistake by typing "ARG ERR" and
what it doesn't like.
.SS DISK - get TV image from disk file
.BEGIN VERBATIM
TTY: DISK FILE_NAME
MP: DISK(STRING FILE_NAME; REFERENCE BOOLEAN FLAG);
OUTPUT: none
ERRORS: 22
.END
This command releases any existing TV buffers and reads in a disk
file, using library routine PICRD, into a TV buffer the exact length of the
data. FILE_NAME is the name of the file and may contain a project-programmer
pair; if none is given, the normal default ppn is assumed. The file read
in must be in the format used by library routines PICRD and PICWR (created
by system program PICTUR or a similar program). The default values of %TMAX%
,%BMAX%, %RSMAX% and %LSMAX% are set from the file's header information.
In this mode the TV camera will never be read. If an edge reaches the edge
of the image read in, it is assumed to be outside the field of view.
The TV accomodation routines are also disabled. If the FINE command is
later executed with the color option on (see {REF(FINE)}) and the file
given does not contain a color picture, a new file name is
requested and, if none is given, %FINE% quits without using color.
FLAG is set false if DISK fails because the file could not be found, no
free disk channels exist, or the picture format was not correct. If executed
from the TTY the string "file_name NOT FOUND" is typed back. FLAG is TRUE
if the file was found all right. If DISK fails, the edge follower is left in
its normal mode, prepared to accept input from the TV. The command INITTV (see {ref(misccom)}) will
force it back into the normal mode if you are done playing with disk files.
DISK can be executed more than once to read in new disk files; each one
replaces the previous file.
.SS GETDATA - get edge follower output
.GETDATA: SUBSECTION!
.BEGIN VERBATIM
TTY: GETDATA ARG
MP: GETDATA(ITEMVAR ARG; REFERENCE BOOLEAN FLAG);
OUTPUT: none
ERRORS: 24
.END
%GETDATA% transfers edge points to the calling job. ARG is the
object item whose edge points are desired or
EVERY. FLAG is set false if
the object does not exist, or the object has no edge points
(COMPACT command has been executed for it); FLAG is true otherwise.
A real array DAT is created and filled with edge points. See {REF(PNTSTR)}
for a descriptin of the format of DAT. DAT will have bounds 1:MAXCNT, 1:4 where
MAXCNT is the number of edge points plus the number of edge segments.
If the command was given from the TTY, DAT will be written onto a disk
file, in text format, with MAXCNT in the first line, followed by DAT[I,J], J=1,4
on each line and I=1,2,..,MAXCNT on the next MAXCNT lines. A file name
will be requested. If a camera
transform exists for the object, it is written out last with the number of lines
it needs on the first line, followed by three real numbers per line. See {REF(CAMTRAN)}
for the format of the camera transform. If the transform does not exist, the
count given is zero and is on the last line of the file.
If the command was given by a message procedure, the calling job is sent
the message SEND_DATA(MAXCNT,DAT). It must be killed by the job receiving it and
need not be acknowledged.
.SS GLBDMP - get curve fitter output
.BEGIN VERBATIM
TTY: GLBDMP ARG
MP: GLBDMP(SET ARGS);
ERRORS: ENTER FAILED
.END
%GLBDMP% dumps the global data structure put out by the curve fitter
(see {REF(CURSTR)}) onto a disk file. The global model
is not changed. If called from the TTY, ARG is the item
number of the object to be dumped, or -1 for the entire data structure,
possibly including objects dumped previously. If called by a message procedure,
ARGS is the set of objects whose structure is to be dumped, which may be a one
item set containing EVERY. EVERY should not be included in sets containing
object items. ↓_This message
procedure must be sent to CURVE, not EDGE_↓.
The command will request a file name, including extension, for the TTY,
no matter how it was excuted, which you must give to job CURVE. All existing
data structure for each object will be written out. The output is
commented and should be understandable but below is the description of the
disk file. * denotes the start of a new line in the file. If you don't want
to read all this, there is a procedure called GLBGET in HELIB which reads
these files and restores the global data structure to its original form.
.BEGIN MACRO IND⊂BEGIN A←A+5; INDENT A,A,0;⊃; A←0; INDENT 0,0,0;
*integer A, the number of objects followed by A data structures. A can be zero
if you asked for all objects and none exist.
.IND
*integer B, the number of vertices for this object, followed by B lines of vertices.
It is zero, as well as all counts below, if the object does not exist, has no
global data structure, or has no closed regions. In the last case, counts C and D
below will be zero and all data will be in the dangling edge array. This will
happen if the last few passes of the curve fitter were disabled when it was run.
.IND
*real X and Y, the coordinates of a vertex
.END
*integer C, the number of edges for this object, followed by C lines of edge data
.A ← A-5;IND
*real L, the length of the edge (always zero from CURVE), followed by two integers
which index into the vertex lines, above, to specify the endpoints of the edge.
.END
*integer D, the number of regions for this object, followed by D lines of region
information. The first line of region info will be the background region.
.A←A-5;IND
*integer E, the number of vertices for this region, followed on the same line by
E integers which index into the vertex lines, above, to specify the vertices of
the region, in clockwise order starting with the lowest vertex in the region.
.END
*integer F, the number of dangling edges, followed by F lines of edge data.
This is zero if all edges are parts of regions.
.A←A-5;IND
*real X1 Y1 X2 Y2, the endpoint coordinates of a dangling line, in random order.
.END
*integer G, the length of the camera transform, followed by G lines of transform
data, three real numbers per line. See {REF(CAMTRAN)} for the contents of the transform.
G is zero if there is no transform for this object. Following this is the start
of the data structure for the next object, if any.
.END
.END
.SS SETVAL - change a variable
.CVAR: SUBSECTION!
.BEGIN VERBATIM
TTY: SETVAL NAME VAL
MP: SETVAL(STRING NAME; INTEGER VAL; REFERENCE BOOLEAN FLAG);
.END
%SETVAL% searches the symbol table for a variable, declared INTERNAL,
called NAME and stores VAL in it. FLAG is false if the variable is not found.
If no variables seen to be present, EDGE was not loaded properly.
No type checking is performed. VAL is normally an integer. From the TTY only,
it will be interpreted as real if a decimal point appears in it. While any
INTERNAL variable can be changed, many should not be. Below is a table of
variables which the user can safely change, along with their initial value.
Some variables can only take on certain values but the command does no checking.
If limits are given, the edge follower will not run unless the variables are
within the limits. Restarting or reinitializing EDGE will reset all variables
to their initial values. See index for other references to help explain what
these variables do.
.COL(0,20,12,,5);
↓_VARIABLE\INITIAL\USE_↓
%XSTRT%\0\X coordinate where the scan starts on next call of the edge
follower's inner loop. If outside
the limits of the scan, it will be initialized to the proper side of the
scan rectangle according to XINCR.
%YSTRT%\0\Y coordinate where scan starts on next call. If outside the
scan rectangle, it will be initialized to the top or bottom of the rectangle,
according to YINCR. If both XSTRT and YSTRT are zero, the scan is initialized
to a corner of the rectangle. They are ∪automatically reset to zero when the
far corner is reached by the scan. Command START resets both of them at once.
%XINCR%\8\X increment for the coarse raster scan by FIND and RELOOK.
A positive value scans left to right; negative values scan right to
left. It must never be zero.
%YINCR%\8\Y increment for the coarse raster scan for FIND and RELOOK.
A positive value scans up; negative values scan down. It must never
be zero.
%TMAX%\10\This and the next three variables define the limits of the
scan rectangle for FIND and RELOOK. The initial values are the limits of the TV
field of view and these limits should never be exceeded. They should not be
altered when using the disk image. This is the top edge.
%BMAX%\250\Bottom edge. BMAX>TMAX must hold.
%LSMAX%\10\Left side.
%RSMAX%\325\Right side. LSMAX<RSMAX must hold.
%SLIM%\0\If zero, edges will be terminated at the edge of the scan
rectangle; if non-zero, tracing will continue outside the rectangle. Scanning
will always stop at the limits of the TV field of view. This affects mainly
FIND and RELOOK; other tracing commands set this internally the way they want
it. Do not set it non-zero when using disk images or you will trace garbage.
%SPACE%\1α.4\The increment the operator is moved when tracing an edge.
1α.0≤SPACE≤CIRCLE*1α.5, where CIRCLE is the radius of the operator, is enforced
by the program; anything outside the limits will be set to the nearest limit.
%TOLSCN%\3α.0\Distance from an edge segment program will realize it has
been seen previously when scanning for an edge. It should not be decreased.
%TOLTRA%\3α.0\Distance from an edge segment program will realize it has
been seen previously when tracing an edge. It should not be decreased.
%CONF%\0α.9\Confidence level for Hueckel operator. 0α.85≤CONF<1α.0 is
recommended.
%DIF%\1α.5\Intensity change for Hueckel operator. 1α.5≤DIF recommended.
%TTHRES%\4\Threshold for difference operator used in coarse scan for FIND
and RELOOK. Threshold used is (TTHRES + (CASE BITS-3 OF (-4, 0, 4, 4)) MAX 2
where BITS is the sample size in bits.
%TVWID%\65\Width of the square read by the TV when tracing in most of the
tracing commands. Command INITTV must be executed immediately after changing TVWID
to set up the next TV buffer.
%TVCAM%\1\TV camera to be read. 2 is the only other acceptable value
(Sierra camera).
%DISTST%\10\When tracing an edge, the display will be updated each DISTST points.
The larger the value, the faster the program will run. The speed vsα. value curve
is fairly flat above 10, however. The display will be updated at the end of each
edge segment regardless of the count, if positive. DISTST<0 disables all displaying.
%CLDIFF%\1\When accomodating, the program enforces BCLIP-TCLIP≥CLDIFF.
If CLDIFF=7, clip level accomodation is disabled. If CLDIFF>7, CLDIFF←7. If
CLDIFF<0, CLDIFF←0.
%NODAC%\0\If non-zero, the target voltage is frozen at its current
setting and will not be changed by the accomodation routines, except the auto
target initialization routine.
.END
.SS GETVAL - look at a variable
.BEGIN VERBATIM
TTY: GETVAL NAME
MP: none
.END
Variable NAME is looked up in the symbol table and, if found, its
value is typed out either as a REAL or INTEGER (octal and decimal), depending
on the whims of the control program. Any INTERNAL variable can be accessed
this way. Those in the list for SETVAL are recommended.
.SS XEQ - miscellaneous commands
.MISCCOM: SUBSECTION!
.BEGIN VERBATIM
TTY: NAME
MP: XEQ(STRING NAME; REFERENCE BOOLEAN FLAG);
.END
The symbol table is searched for NAME, which must be declared INTERNAL,
and executes it as a SAIL subroutine with no arguments. If %XEQ% was called,
FLAG is false if NAME cannot be found. The string "COM ERR" followed by the
command is typed if it was executed from the TTY. Below
is a list of the %miscellaneous commands%
.COL(0,10,0,,5);
↓_NAME\DESCRIPTION_↓
%.GARCO%\forces garbage collection of edge follower's data structure
(usually happens automatically as needed)
%RESTAR%\reinitializes the edge follower's display, data structure,
image input device (to TV), and control variables
%START%\resets scan to original starting point
%EDGTYP%\sets global typing flag for EDGE to true to allow typeout
when monitor is not running. Normally off.
%CHANGE%\forces reaccomodation for next scan. To be used when the
scene the TV is looking at is changed.
%EDGEON%\(only on III display) turns on the edge follower debugging. A
point is moved around the scene to show where the program is looking. Various
data is dumped on disk file EDGn.DBG, where n is the monitor run number; 0 if
no monitor. If you answer "Y" to the question "DELAY?", the program will stop
after each call of the Hueckel operator and all its output variables and flags
will be displayed, as well as being dumped on the disk file. <CR> will allow the
program to continue. If you answer anything else to the question, there will be
no stops.
%EDGOFF%\turns off edge follower debugging (normal case)
%TIMEIN%\stores the current clock time and program run time for EDGE
%TIMOUT%\types elapsed time and run time since TIMEIN was last called
%INITTV%\set TV input (normal case). For use after DISK command or
TVWID was changed. Creates a TV buffer of at least 500 words, larger if
necessary, and forces new accomodation.
%COLON%\turns on color edge tracing for FINE command.
%COLOFF%\negates COLON (normal case)
%DMODE%\(only on III display with live images) enter special debugging
mode. Procedure INP in HELIB is called to set the area you want to scan. Then
that area is scanned with the Hueckel operator and an increment equal to the
radius of the operator. At each point the display described under EDGEON appears
and the line "DMODE: Accom,Exit,Video,Trace,Dump" is typed to remind you of the
responses it likes. Upon typing a <CR>, possibly preceded by one of the response
characters, the program types "YOPER=", followed by the operator flag decoded as
follows:
.COL(15,20,0);PREFACE 0;
-1\outside field of view
0\nothing seen
1\noise seen
2\blew up
3\edge seen
.END CONTINUE
If YOPER>0 the program types "SEEN=" and "PNTR=" with their values. If
SEEN>0 the point has been seen before as part of an edge, SEEN is the object number
and PNTR points to the point in the data structure. If SEEN=0, it has not been seen
before. Finally, the response character you typed is decoded as follows:
.COL(15,20,25)
Y\exit from this command
T\call the edge tracing routine to attempt to trace an edge at the current
point.
V\send the current TV buffer to DDVID, using the VIDEO routine in HELIB
A\try to accomodate in this area.
D\dump the current TV buffer onto the disk, using library routine PICWR.
A file name will be requested.
.END CONTINUE; skip 1;
Any other response character is ignored. After decoding the character and
taking the specified action, if any, the program will continue to the next point,
except for responses A and V, which return to process the same point again.
%PTSHOW%\a square grid is displayed over the normal display. A number
in the center of each square gives the number of edge points in the area of the
image the square covers. It is displayed to show the complexity of the various
parts of the scene.
%ACCON%\turns on accomodation debugging [details may follower later]
%ACCOFF%\turns off accomodation debugging (normal case)
.END
.SEC(STRINGS OUTPUT BY PROGRAMS)
.SS(INFORMATION OUTPUT)
.OUTPUT: SUBSECTION!
.MACRO HEAD(A) ⊂BEGIN SKIP 2; CENTER}A{END;⊃;
These strings are typed only if the global typing flag for EDGE is
true.
.COL(0,10,5,69); AT "*" ⊂}\#{⊃;
.HEAD(file EDGE)
1\KKP: SCAN OUTSIDE*
Edge follower traced an edge to the limit of the field of view
2\EDGE LOST*
Edge follower lost an edge and could not recover it
3\KKP: LOOPING*
Edge follower is looping while tracing, usually due to noise, and cannot
recover. The current edge is terminated.
4\KKP: ACCOM FAILED*
The accomodation routines were not able to improve edge contrast when an edge was
lost. The current edge is terminated.
5\KKP: NO POINTS*
Tracing routines found no edge point where they were directed to start tracing.
6\SCAN REVERSED - EDGE*
Edge follower terminated tracing of an edge and is now attempting to extend the
other end of the edge, which has not been previously traced.
7\KKP: OBJECT TOO SMALL*
The number of edge points for the object just traced is below the minimum.
8\DELETED*
Normally typed after another string. Indicated that, as a result of the last
string, the current object is being deleted.
9\KKP: POINT SEEN BEFORE*
Tracing for the current object just started and the first edge point found has
been seen before.
10\OPER 1 WON!!*
Switching to the smaller Hueckel operator succeeded after failing with the larger one.
11\SEGMENT CLOSED*
While tracing an edge, the opposite end of the edge has been encountered. We now
have a closed outline. The absence of this message does not necessarily mean that
a closed outline was not found.
12\MERGED SEGMENTS*
While tracing an edge, the end of another edge has been encountered. The two
edge segments have been merged.
13\HIT ANOTHER SEGMENT*
While tracing an edge, another edge has been encountered, but not at its end. The
current edge is terminated and linked to the same object as the other edge.
14\FINE CORNER x,y*
An edge was lost and never extended. At the end of the trace for the current
object the program notices this and does a fine scan with the Hueckel operator in
the area where the edge was lost to try to find it again.
.HEAD(file SCANER)
15\DAC SET AT n AD=m*
Accomodation routines have changed TV sensitivity. You are given the new DAC setting
and corresponding AD reading.
16\AUTO TARGET SET AT n*
The autotarget voltage has been recalibrated and you are given the new DAC setting.
17\lab:TCLIP=m BCLIP=n*
Accomodation routine lab has changed the clip levels, which are given to you.
18\CLIPS RETAINED*
Some accomodation routine tried to reaccomodate and failed to find better settings.
The current ones are being retained.
.END
.SS(ERROR OUTPUT)
.ERROR: SUBSECTION!
These strings inform you of errors and special conditions. They
will always be typed, regardless of the typing switches.
.COL(0,10,5,69); AT "*" ⊂}\#{⊃;
.MACRO HEAD(A) ⊂BEGIN SKIP 2; CENTER}A{END;⊃
.HEAD(file TVIN)
1\TV DATA MISSED - TVIN*
Data channel for TV is continuously missing data. Probably
a hardware problem.
2\SYS ERROR - TVIN*
System is about to crash. This error message has never been seen.
3\PARITY ERROR - TVIN*
Data channel for TV is continuously getting parity errors. This
is a hardware problem.
4\CAN'T INIT TV. TYPE CHAR TO RETRY*
Someone has your TV camera. Go yell at him. Then type anything
at the program to try again.
5\TV IS HUNG*
Did you remember to turn on the TV before trying to read it?
.HEAD(file OP);
6\ATTEMPT TO TAKE SQRT OF NEGATIVE ARG*
The Hueckel operator just blew up.
.HEAD(file FAIPRO);CONTINUE;SKIP 2;
All of these error messages result from the edge follower's data
structure being garbaged. They are all software errors.
7\NO STATUS BITS - PTPNT
8\TWO RIGHT ENDS - GETEND
9\TWO LEFT ENDS - GETEND
10\ONE ONE END - GETEND
11\ENDS OUT OF SEQUENCE - GETEND
.HEAD(file DACO);
12\DATA MISSED ON 25 CONSECUTIVE TRIES - AD*
The A-D converter is missing data. Either a hardware error or
someone else is using it in spacewar mode.
13\HUNG DEVICE AD*
Normally means the PDP-6 is not running. Can also be caused by
spacewar mode users of A-D.
14\DACO TIMED OUT*
The A-D reading code is hung up. Spacewar mode users are bad
guys again, probably. Before you feel too smug, let me point out
that this program is also running in spacewar mode. It does, however,
contain special code to insure it does not damage programs using the
A-D with the system code. It is not too nice to other spacewar mode
users.
15\TYPE <CR> TO CONTINUE - ANYTHING ELSE<CR> TO RETRY*
This is the second line of all DACO error messages. If you continue
without retrying, the result depends on which program called it.
.HEAD(file TELL);
16\device INITED BY JOB α{n/NONEα} PPN=pppn*
This is a general purpose message put out by many parts of the program.
'device' is an I/O device (probably TV or AD). The program tried to
initialize the device and found that someone else had it. 'n' is the
number of the job who has it and 'pppn' is the project-programmer pair
the job is logged in under. NONE for job means the culprit disappeared
before the program could nail him.
.HEAD(file EDGE)
17\NO FREE FRAMES*
A new display frame is needed for a new object and no frames are available.
The display routines are disabled until new frames are available.
18\NO DEBUGGING ON THIS DEVICE*
Some debugging modes only operate on III displays. You have tried to use
one of them on some other type of console.
19\DPY/DISPLAY TURNED OFF*
The display program has overflowed its display buffer. No more points will
be displayed for this object.
20\NO STATUS BITS - REVERSE*
Data structure garbaged
21\IGL PNTLST*
Data structure garbaged
.HEAD(file MISEDG)
22\INPUT FAILED*
Attempt to read in a disk image failed. See next message.
23\REQUESTED COLOR NOT IN THIS FILE*
You are executing FINE command with color tracing specified and using disk input.
The disk file currently opened does not contain the needed color image. For both
this and the last message, the program then requests a new file name. If a null
name is given, FINE is terminated and INITTV is executed.
24\FLAG MISSING - GETDATA*
Data structure garbaged.
.HEAD(file INNER)
25\GET_BOX SCREWED UP*
The COMPACT command failed - program bug.
.HEAD(fileSCANER)
26\SENSITIVITY CONTROL IS HUNG - TYPE ANY CHAR TO CONTINUE*
The accomodation routines discovered that the sensitivity cannot be
changed. Probably the controls are on manual. Try to correct and
type a character to try again.
27\I1/I2 TOO LARGE/SMALL*
Set of four messages. The accomodation routines have set the clip levels
outside the proper range. They are set to the closest limit of that range.
.HEAD(file CURVE)
28\GETMAX LOST BIG*
Curve fitter bug
29\SUM ARRAY OVERFLOW*
First pass of curve fitter broke object into too many segments for current
array declarations. Recompile with larger declarations or look at simpler objects.
30\ODAT OVERFLOW*
curve fitter output data structure too complex for arrays. Must be recompiled.
.END
.SEC DATA STRUCTURES
.SS EDGE OUTPUT DATA STRUCTURE
.PNTSTR: SUBSECTION!
The data structure produced internally by the edge follower is
converted to an output structure by the %GETDATA% command and can be
dumped on the disk or passed to another job. It is also generated and
passed to CURVE by means of a message procedure when curve fitting.
An array, DAT, is created, with bounds 1:MAXCNT,1:4 where MAXCNT
is the number of edge points plus the number of edge segments. Each
segment is together in DAT, preceded by control information, with the
points stored in order around the object in the direction the edge
was initially traced, and one object following another.
DAT[J,1], where J is the first word in DAT for a
given segment, contains the count of the number of coordinates for this
segment. DAT[J,2] is the index in
DAT of the start of the next segment, or zero if this is the last segment.
DAT[J,3] is the item number of the object, if this is the beginning of a
new object; zero otherwise. DAT[J,4] is true
if this is a closed segment, of which there is
only one per object; it is false otherwise.
Therefore, the next count is in DAT[DAT[J,2],1]. The coordinates and gradient follow
the count and index, with X in DAT[J+n,1], Y in DAT[J+n,2], the horizontal component
of the gradient in DAT[J+n,3], and the vertical component of the gradient in
DAT[J,n,4], n=1,2,α.α.α.,DAT[J,1].
.BEGIN VERBATIM
J DAT[J,1] DAT[J,2] DAT[J,3] DAT[J,4]
m 3.0 m+4.0 4027.0 0.0
m+1 X1 Y1 CL1 SL1
m+2 X2 Y2 CL2 SL2
m+3 X3 Y3 CL3 SL3
m+4 cnt (m+4)+cnt+1 0.0 0.0
m+5 X11 Y11 CL11 SL11
m+6 X21 Y21 CL21 SL21
etc.
.END
.SS EDGE INTERNAL DATA STRUCTURE
.EDGSTR: SUBSECTION!
The following description of the edge follower's internal
data structure is included mainly to aid the author's memory when
debugging it. It makes more sense if you understand LPS. Single
arrows are link pointers. Double arrows are ring pointers.
.BEGIN VERBATIM
.MACRO AG ⊂APART; GROUP; SKIP 1;⊃; GROUP;
TOPLST
↓
__________________
| TOP |
| OBJPNT | NULL |
|________________|
.AG
OBJLST (last object processed-one for each object)
↓
______________________ OBJPNT
| OBJECT | ↓
| OBJRNG |↔↔↔↔↔↔↔↔↔↔↔↔↔↔↔↔↔
| CORPNT | OUTLIN |
|----------------¬¬¬¬| STATUS BITS (in octal)
|PNTNUM (# of points)|
|DISFRM (frame #) | 1 OR of bits 1-4 from SEGMNT blocks
|OBJNUM (item) |
|TOP (min y coord.) | 10 all segments have been curve fitted
|BOT (max y coord.) | 20 compacted
|LEFT (min x coord.) | 40 inside scanned by FINE or GUNTRACE
|RIGHT (max x coord.)| 100 status returned to calling program
|CAMERA TRANS. (item)| 200 object entirely outside field of view
|____________________|
.AG
**** THE STRUCTURE BELOW EXISTS UNTIL COMPACTED ****
SEGLST (last processed - one for each line segment)
↓
_____________ OUTLIN
| SEGMNT | ↓ STATUS BITS
| SEGRNG |↔↔↔↔↔↔↔↔↔
|SEGPNT|NULL| 1,2,4 OR of all POINT status bits 1-4
|___________| 40 segment has been curve fit
.ag
PNTLST (last processed - one for each edge point)
↓
___________ SEGPNT STATUS BITS
| POINT | ↓ 1 lost edge (bit 10 or 20 set also)
| PNTRNG |↔↔↔↔↔↔↔ 2 intersected another edge "
| WORLDR |↔↔↔↔↔↔↔ 4 scan went outside field of view "
|---------| ↑ 10 no right extension of ring
| X | WORLDP 20 no left extension of ring
| Y | (from 40 bit 1 was set and fine scan done in vicinity
|_________| world model)
.AG
**** STRUCTURE BELOW EXISTS ONLY AFTER COMPACTING ****
_____________ WORLDP (one for each grid square each
| SEGMNT | ↓ line passes through)
| SEGRNG |↔↔↔↔↔↔
|SEGPNT|NULL|
|___________|
.AG
SEGPNT (one for each line)
↓
__________________ CORPNT
| LINE | ↓
| CORRNG |↔↔↔↔↔↔↔↔↔↔
|----------------|
| A (coef. of |
| B line |
| C equation)|
| X1 (first |
| Y1 endpoint) |
| X2 (second |
| Y2 endpoint) |
| D (A↑2+B↑2) |
|________________|
.AG
**** WORLD MODEL ****
PTSEEN TABLE (one entry for each grid square)
↓
______________
| LNK |
|DWN | NULL |
|____________|
|PTSEEN INDEX|
|____________|
.AG
¬¬¬¬¬¬¬¬¬¬¬¬¬¬ DWN
| WORLD | ↓ STATUS BITS
| SQRING |↔↔↔↔↔↔↔↔ 128 compacted
| WORLDP|NULL|
|------------|
|OBJECT item |
|____________|
WORLDP points to ring of point blocks,
or a segment and line block if compacted.
.APART; END;
.SS GLOBAL DATA STRUCTURE FROM CURVE
.CURSTR: SUBSECTION!
.BEGIN TURN OFF "←";
.AT "*" ⊂BEGIN SKIP 2; CRBREAK;CENTER⊃;
.AT "~" ⊂SKIP 2; END; CONTINUE⊃;
The final output of EDGE and CURVE is a data structure in the global
model which describes the objects traced. The %GLBDMP% command will dump
this data structure onto the disk to save it. Library routine %GLBGET% will
read in files produced by GLBDMP and put the structure back in the world
model. In the description below $ means GLOBAL.
For each object, OBJ is the item assigned the object by EDGE by which
you have been refering to the object. For each vertex of the object
*VER ← $ NEW(FOO)
$ MAKE POINT⊗OBJ≡VER
$ DATUM(FOO)[1] ← X coordinate
$ DATUM(FOO)[2] ← Y coordinate
~The only vertex points in these associations
are those which bound closed regions of the object; all other vertex points can
be found in the DANGLE association. If there are no closed regions for this
object, then the POINT, LINE, EDGPT, REGION, PERIMETER, and BACKGROUND associations
described below will not exist.
For each line of the object
*LN ← $ NEW(0.0)
$ MAKE LINE⊗OBJ≡LN
$ MAKE ENDPT⊗OBJ≡VER1
$ MAKE ENDPT⊗OBJ≡VER2
~where VER1 and VER2 are the vertex items of the endpoints of this line.
Foreach region of the object
*REG ← $ NEW
$ MAKE REGION⊗OBJ≡REG
PER ← $ NEW(PHI)
$ MAKE PERIMETER⊗REG≡PER
$ DATUM(PER)[I] ← VERi
~where VERi are the i vertices of the region, clockwise, starting with
the lowest in the image. For the background region, REGB, which is the region
bounded by the outermost edges of the object which form closed regions,
*$ MAKE BACKGROUND⊗OBJ≡REGB~
Next we have
*$MAKE DANGLE⊗OBJ≡$ NEW(ARY)
~where ARY is a real array with
bounds 1:J,1:4 containing X1, Y1 and X2, Y2, the coordinates of the endpoints
of the J lines of the object which are not part of the closed regions. This
association does not exist if J=0.
Finally, there is
*$ MAKE XFORM⊗OBJ≡$ NEW(CT)
~where CT is a real array
containing the camera transform. It exists only if a transform exists for
this object. See {REF(CAMTRAN)} for a description of the camera transform.
.END
.SS CAMERA TRANSFORM
.CAMTRAN: SUBSECTION!
The camera transform is created by job CAMERA and is normally found
in the global real array CAMERA_MODEL. Whenever EDGE starts tracing a
new object it makes a copy of this array, if it exists, and links it to
the object item. In this way, the camera can be moved between successive
calls on EDGE and each object will still have the correct transform.
The transform contains information on the status of the cameras when the
object was traced and the matrices needed to convert from the TV coordinate
system to the table coordinate system used by the arm, and back.
The transform is a 10x3 array with the information stored as follows:
.COL(10,20,25,,5);
1:3,1:3\is the colineation matrix (TABLE → TV)
4,1:3\is the lens center in table coordinates
5,1:2\is the TV coordinates of the point on the image plane pierced
by the axis of the lens.
5,3\is always 1
6:8,1:3\is the inverse colineation matrix (TV → TABLE)
9,1:3\contain the pot readings, in radians, for pan, tilt, and focus
10,1\is the camera number
10,2\is the lens number (COHU) or pot reading, in radians, for the
zoom lens (SIERRA)
10,3\is always 0
.end
.STANDARD BACK